/*
 * JSFConsole - Lightweight JSF Application Monitor
 * Copyright (C) 2009  Grzegorz Bugaj
 * http://www.gregbugaj.com
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/
package com.gregbugaj.reflector.renderer;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.gregbugaj.jsfconsole.util.XMLUtil;
/**
 * Renders  given object into HTML Table
 * @author devil
 *
 */
public class TreeRenderer extends AbstractRenderer{
	@Override
	protected  void emitObject(Node node, EmitContext context) throws Exception  {	
		c("<table class='object' opath=\""+XMLUtil.attributeText(node, "opath")+"\">");
		
		c("<tr> <td>");
		c("<dl>");
		c("<dt>");
		if(node.getAttributes().getNamedItem("class")!=null){
			c(XMLUtil.attributeText(node,"class"));
		}

		if(node.getAttributes().getNamedItem("name")!=null){
			c(" "+XMLUtil.attributeText(node,"name"));
		}
		c("</dt>");

		NodeList fields = XMLUtil.extract("fields/*", node);
		NodeList methods = XMLUtil.extract("methods/*", node);
		c("<dd>");
		for(int i=0;i<fields.getLength();i++){
			emit(fields.item(i), null);
		}
		for (int i = 0; i < methods.getLength(); i++) {
			emit(methods.item(i), null);
		}
		c("</dd>");
		c("</dl>");
		c("</td>");
		c("</tr>");		
		c("</table>");
	}

	@Override
	protected  void emitArrayField(Node node, EmitContext context)	throws Exception {
		String opath=XMLUtil.attributeText(node, "opath");
		if(context.getOpath()!=null){
			opath=context.getOpath();
		}
		c("<table class='array' opath=\""+opath+"\">");

		c("<tr> <td>");
		c("<dl>");
		c("<dt>");
		c("<a href='javascript:void(0);' onclick='toggleCollectionView(this);' class='box'>-</a>"); 

		c(XMLUtil.attributeText(node, "type"));		
		c("  ");
		if(context.isNameEnabled()){
			c(XMLUtil.attributeText(node, "field"));
		}
		c("</dt>");

		NodeList entrySet = XMLUtil.extract("./*", node);
		c("<dd>");
		for (int i = 0; i < entrySet.getLength(); i++) {
			Node entry=entrySet.item(i);
			//c("<table class='array-entry'>");
			c("<table class='array-entry' opath=\"["+i+"]\">");
			c("<tr> <td class='array-index'>");
			c("["+i+"] ");
			c("</td>");
			//c("<td class='array-value' opath='["+i+"]'>");
			c("<td class='array-value'>");
			EmitContext nContext=new EmitContext();
			nContext.setNameEnabled(false);
			nContext.setOpathEnabled(false);
			
			emit(entry, nContext);
			c("</td>");
			c("</tr>");		
			c("</table>");	
		}
		c("</dd>");
		c("</dl>");
		c("</td>");
		c("</tr>");		
		c("</table>");
	}

	@Override
	protected  void emitCollectionField(Node node, EmitContext context)	throws Exception {
		
		c("<dl opath=\""+XMLUtil.attributeText(node, "opath")+"\">");
		c("<dt class='collection'");
		c("<a href='javascript:void(0);' onclick='toggleCollectionView(this);' class='box'>-</a>"); 
		c(XMLUtil.attributeText(node, "type"));		
		c("  ");
		if(context.isNameEnabled()){
			c(XMLUtil.attributeText(node, "field"));
		}
		c("</dt>");
		c("<dd>");
		NodeList entrySet = XMLUtil.extract("./*", node);	
		for (int i = 0; i < entrySet.getLength(); i++) {	
			EmitContext nContext=new EmitContext();
			nContext.setNameEnabled(false);
			emit(entrySet.item(i), nContext);
		}
		c("</dd>");
		c("</dl>");		
	}

	@Override
	protected  void emitMethod(Node node, EmitContext context) throws Exception {
		/*
		c(XMLUtil.attributeText(node, "signature") +" : ");
		NodeList retValueList = XMLUtil.extract("./*", node);		
		if(retValueList.getLength()>0){
			emit(retValueList.item(0)); 
		}else{
			c("NULL");
		}
		 */
	}


	@Override
	protected void emitField(Node node, EmitContext context) throws Exception {
		String objRefId=XMLUtil.attributeText(node, "objRefId");
		String opath=XMLUtil.attributeText(node, "opath");
		if(context.getOpath()!=null){
			opath=context.getOpath();
		}
		if(context.isOpathEnabled()){
			c("<table class='field' objRefId='"+objRefId+"' opath=\""+opath+"\">");
		}else{
			c("<table class='field' objRefId='"+objRefId+"'>");
		}
		
		c("<tr> <td>");
		c(XMLUtil.attributeText(node, "type")+" ");

		if(context.isNameEnabled()){
			c(XMLUtil.convertAsciiToXml(XMLUtil.attributeText(node, "name"))+" ");
		}

		c(XMLUtil.convertAsciiToXml(XMLUtil.attributeText(node, "value")));
		c("</td> </tr>");		
		c("</table>");
	}

	@Override
	protected void emitMap(Node node, EmitContext context) throws Exception {
		//c("<table>");
		//c("<tr> <td>");
		c("<dl>");
		c("<dt class='map'>");
		c("<a href='javascript:void(0);' onclick='toggleCollectionView(this);' class='box'>-</a>"); 
		c( XMLUtil.attributeText(node, "type")+"  "+  XMLUtil.attributeText(node, "field")); 
		c("</dt>");
		c("<dd opath=\""+XMLUtil.attributeText(node, "opath") +"\">");
		NodeList entrySet = XMLUtil.extract("./entry", node);
		for (int i = 0; i < entrySet.getLength(); i++) {
			Node entry=entrySet.item(i);
			Node keyNode = XMLUtil.extract("./*[1]", entry).item(0);	
			Node valueNode = XMLUtil.extract("./*[2]", entry).item(0);	

			EmitContext keyContext=new EmitContext();
			keyContext.setNameEnabled(false);
			String mapOpath=XMLUtil.attributeText(keyNode, "value");
			keyContext.setOpath("[\'"+mapOpath+"\']");
			c("<table>");
			c("<tr> <td>");
			emit(keyNode, keyContext);
			c("</td> <td>");
			emit(valueNode, keyContext);
			c("</td> </tr>");
			c("</table>");
		}	
		c("</dd>");

		c("</dl>");
		//c("</td> </tr>");		
		//c("</table>");
	}

	@Override
	protected void emitReference(Node node, EmitContext context) throws Exception {
		String value=XMLUtil.attributeText(node, "value");
		String refId=XMLUtil.attributeText(node, "refId");
		c("<table class='reference'>");
		c("<tr> <td>");		
		c("<a href='javascript:void(0)' onclick=\"focusRef('"+refId+"')\">");
		c("Ref #"+ value);
		c("</a>");
		c("</td> </tr>");
		c("</table>");
	}

}
